package com.du.common.base.util;

import javax.crypto.Cipher;
import java.security.*;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.Base64;

/**
 * @Desc :
 * @Author: shuangdu
 * @date : 2023/9/26
 */
public class RSAExample {
    private static final String ALGORITHM = "RSA";

    public static void main(String[] args) throws Exception {
        // 生成公钥和私钥
        KeyPairGenerator keyPairGenerator = KeyPairGenerator.getInstance(ALGORITHM);
        keyPairGenerator.initialize(1024);
        KeyPair keyPair = keyPairGenerator.generateKeyPair();
        PublicKey publicKey = keyPair.getPublic();
        PrivateKey privateKey = keyPair.getPrivate();
    }

    /**
     * 加密数据
     * @param plaintext 明文数据
     * @param publicKey 公钥字符串
     * @return 密文数据
     * @throws Exception 加密异常
     */
    public static byte[] encryptWithPub(String plaintext, String publicKey) throws Exception {
        byte[] plaintextBytes = plaintext.getBytes();
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PublicKey pubKey = keyFactory.generatePublic(keySpec);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, pubKey);
        return Base64.getEncoder().encode(cipher.doFinal(plaintextBytes));
    }

    public static byte[] encryptWithPri(String plaintext, String privateKey) throws Exception {
        byte[] plaintextBytes = plaintext.getBytes();
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKey);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PrivateKey priKey = keyFactory.generatePrivate(keySpec);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, priKey);
        return Base64.getEncoder().encode(cipher.doFinal(plaintextBytes));
    }

    /**
     * 解密数据
     * @param cipherText 密文数据
     * @param privateKey 私钥字符串
     * @return 明文数据
     * @throws Exception 解密异常
     */
    public static String decryptWithPri(byte[] cipherText, String privateKey) throws Exception {
        byte[] cipherTextBytes = Base64.getDecoder().decode(new String(cipherText));
        byte[] privateKeyBytes = Base64.getDecoder().decode(privateKey);
        PKCS8EncodedKeySpec keySpec = new PKCS8EncodedKeySpec(privateKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PrivateKey priKey = keyFactory.generatePrivate(keySpec);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, priKey);
        return new String(cipher.doFinal(cipherTextBytes));
    }

    public static String decryptWithPub(byte[] cipherText, String publicKey) throws Exception {
        byte[] cipherTextBytes = Base64.getDecoder().decode(new String(cipherText));
        byte[] publicKeyBytes = Base64.getDecoder().decode(publicKey);
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKeyBytes);
        KeyFactory keyFactory = KeyFactory.getInstance(ALGORITHM);
        PublicKey pubKey = keyFactory.generatePublic(keySpec);
        Cipher cipher = Cipher.getInstance(ALGORITHM);
        cipher.init(Cipher.DECRYPT_MODE, pubKey);
        return new String(cipher.doFinal(cipherTextBytes));
    }
}
